// TASK_2View.cpp : implementation of the CTASK_2View class
//

#include "stdafx.h"
#include "TASK_2.h"

#include "TASK_2Doc.h"
#include "TASK_2View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CTASK_2View

IMPLEMENT_DYNCREATE(CTASK_2View, CView)

BEGIN_MESSAGE_MAP(CTASK_2View, CView)
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
END_MESSAGE_MAP()

// CTASK_2View construction/destruction

CTASK_2View::CTASK_2View()
{
	// TODO: add construction code here

}

CTASK_2View::~CTASK_2View()
{
}

BOOL CTASK_2View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
#define SIGN(x) ((x)>0?1:((x)==0?0:-1))
#define ABS(x) ((x)>0?(x):-(x))

void swap(LONG *x, LONG *y)
{
    (*x) ^= (*y);
    (*y) ^= (*x);
    (*x) ^= (*y);
}

void swapPoint(POINT *x, POINT *y)
{
    POINT t;
    t = *x;
    *x = *y;
    *y = t;
}

void BresenhamLine(CDC *pDC, POINT start, POINT end, COLORREF crColor)
{
    LONG dx, dy, dd;
    LONG p, upperX;
    LONG sign, sign2;
    POINT dot;

    // Steep Check.
    sign = SIGN(ABS(end.x  - start.x) - ABS(end.y - start.y));
    if (sign > 0) {
    }
    else if (sign == 0) {
    }
    else {
        swap(&start.x, &start.y);
        swap(&end.x, &end.y);
    }
    // Start point check.
    if (start.x > end.x) {
        swapPoint(&start, &end);
    }
    // Negative or positive
    sign2 = end.y - start.y;
    if (sign2 < 0) {
        start.y = -start.y;
        end.y = -end.y;
    }

    dot = start;
    upperX = end.x;

    // Initialize and draw.
    dx = end.x - start.x;
    dy = end.y - start.y;
    dd = (dy - dx) << 1;
    p = (dy << 1) - dx;
    while (dot.x <= upperX) {
        if (sign > 0 && sign2 >= 0) {
            pDC->SetPixel(dot.x, dot.y, crColor);
        }
        else if (sign < 0 && sign2 >= 0) {
            pDC->SetPixel(dot.y, dot.x, crColor);
        }
        else if (sign > 0 && sign2 < 0) {
            pDC->SetPixel(dot.x, -dot.y, crColor);
        }
        else {
            pDC->SetPixel(-dot.y, dot.x, crColor);
        }
        if (p < 0) {
            p += dy;
        }
        else {
            dot.y++;
            p += dd;
        }
        dot.x++;
    }
}

/////////////////////////////////////////////////////////////////
void plotCirclePoint(CDC *pDC, POINT p, POINT c, COLORREF crColor)
{
    pDC->SetPixel(c.x + p.x, c.y + p.y, crColor);
    pDC->SetPixel(c.x + p.x, c.y - p.y, crColor);
    pDC->SetPixel(c.x - p.x, c.y + p.y, crColor);
    pDC->SetPixel(c.x - p.x, c.y - p.y, crColor);
    pDC->SetPixel(c.x + p.y, c.y + p.x, crColor);
    pDC->SetPixel(c.x + p.y, c.y - p.x, crColor);
    pDC->SetPixel(c.x - p.y, c.y + p.x, crColor);
    pDC->SetPixel(c.x - p.y, c.y - p.x, crColor);
}

void BresenhamCircle(CDC *pDC, POINT center, LONG diameter, COLORREF crColor)
{
    POINT p;
    LONG d;

    p.x = 0;
    p.y = diameter;
    d = 3 - (diameter << 1);
    while (p.x <= p.y) {
        plotCirclePoint(pDC, p, center, crColor);
        if (p.x % 5 == 0) {
            BresenhamLine(pDC, center, p, crColor);
        }
        if (d < 0) {
            d += (p.x << 2) + 6;
        }
        else {
            d += ((p.x - p.y) << 2) + 10;
            p.y--;
        }
        p.x++;
    }
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
// CTASK_2View drawing

void CTASK_2View::OnDraw(CDC* /*pDC*/)
{
	CTASK_2Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
    /////////////////////////////////////////////////////////////
    CDC *pDC = this->GetDC();
    /////////// Draw Line Using Bresenham Algorithm /////////////
    //POINT start = {100, 100};
    //POINT end = {200, 300};
    //POINT end = {50, 200};
    COLORREF crColor = RGB(255, 0, 0);
    //BresenhamLine(pDC, start, end, crColor);
    /////////// Draw Circle Using Bresenham Algorithm //////////
    POINT center = {100, 100};
    LONG diameter = 50;
    BresenhamCircle(pDC, center, diameter, crColor);
    /////////////////////////////////////////////////////////////
    ReleaseDC(pDC);
    /////////////////////////////////////////////////////////////
	if (!pDoc)
		return;

	// TODO: add draw code for native data here
}


// CTASK_2View printing

BOOL CTASK_2View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CTASK_2View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CTASK_2View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}


// CTASK_2View diagnostics

#ifdef _DEBUG
void CTASK_2View::AssertValid() const
{
	CView::AssertValid();
}

void CTASK_2View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTASK_2Doc* CTASK_2View::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTASK_2Doc)));
	return (CTASK_2Doc*)m_pDocument;
}
#endif //_DEBUG


// CTASK_2View message handlers
